/**
 * useReducer
 *
 *    概念：
 *     用于替代 useState 的一个新 hook.
 *     它允许你向组件里面添加一个 reducer
 *     reducer 是一个纯函数，【得到 state 的一个函数】
 *        根据当前的 state 与 action 生成一份全新的 state 的纯函数
 * 
 *    语法：
 *        const [state, dispatch] = useReducer(reducer, initialArg, init?)
 *          
 *          1. reducer - 纯函数
 *          2. initialArg - 初始数据
 *          3. init - 可选的产生初始数据的一个函数
 *          4. state - 状态数据
 *             1. 初始值由 initialArg 决定
 *             2. 后续的更新由 reducer 函数的返回值来决定
 *          5. dispatch - 派发器【派发动作的一个函数】
 * 
 *    reducer：
 *       (prevState, action) => newState
 * 
 *    action:
 *      动作，一般是一个包含有 type 属性的对象，比如 { type: 'INCREMENT' }
 *    
 *    dispatch:
 *      派发器，用于派发动作 dispatch(action)。
 *      动作的派发会触发 reducer 函数的执行, action 会作为 reducer 第二个参数
 *        
 * 
 *    
 *
 *    纯函数：
 *      相同的输入一定会产生相同的输出，不受外部影响，不会去影响外部（不包含副作用）的函数就叫做纯函数
 * 
 *      let a = 10;

        function fn1() {
          return "111";
        }

        // 不纯，使用了外部数据
        function fn2() {
          return a + "111";
        }

        // 纯
        function fn3(a, b) {
          return a + b;
        }

        // 不纯，相同的输入不一定产生相同的输出
        function fn4(a, b) {
          return a + b + Math.random();
        }

        // 不纯，包含有副作用的代码
        function fn5() {
          // 操作DOM
          // 操作网络请求
          // 消息订阅
          // 修改 state 数据
        }
 *
 */

import React, { useReducer } from "react";

/**
 * reducer
 * @param state
 * @param action
 * PS:
 *    1. 不能改变现有数据，一定要返回一份全新的 state
 */
const reducer = (state, action) => {
  console.log("reducer state", state);
  console.log("reducer action", action);
  switch (action.type) {
    case "INCREMENT":
      // state.count++;
      // return state;
      return {
        ...state,
        count: state.count + 1,
      };
    case "DECREMENT":
      return {
        ...state,
        count: state.count - 1,
      };
    default:
      return {
        ...state,
      };
  }
};

/**
 * 初始 state 数据
 */
const defaultState = {
  count: 0,
};

export default function App() {
  const [state, dispatch] = useReducer(reducer, defaultState);

  // 1. 初始值由 initialArg 决定
  console.log("state", state);

  return (
    <div>
      <h1>App</h1>
      <button>{state.count}</button>
      <button
        onClick={() => {
          // 修改 state，需要调用 派发器
          dispatch({ type: "INCREMENT" });
        }}
      >
        自增
      </button>
      <button
        onClick={() => {
          // 修改 state，需要调用 派发器
          dispatch({ type: "1DECREMENT" });
        }}
      >
        自减
      </button>
    </div>
  );
}
